﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;

namespace SmartSiteManagementSystem.Utils
{
    public class RegexUtils
    {
        public RegexUtils()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
        }

        /// <summary>
        /// //验证是否包含数字
        /// </summary>
        /// <param name="strIn"></param>
        /// <returns></returns>
        public static bool IsValidContainsFigure(string strIn)
        {
            return Regex.IsMatch(strIn, @"(\d+)");
        }

        /// <summary>
        /// //验证是全为数字
        /// </summary>
        /// <param name="strIn"></param>
        /// <returns></returns>
        public static bool IsValidFigure(string strIn)
        {
            return Regex.IsMatch(strIn, @"^(\d+)$");
        }

        /// <summary>
        /// //验证Email地址
        /// </summary>
        /// <param name="strIn"></param>
        /// <returns></returns>
        public static bool IsValidEmail(string strIn)
        {
            return Regex.IsMatch(strIn, @"^[A-Za-z0-9](([_\.\-]?[a-zA-Z0-9]+)*)@([A-Za-z0-9]+)(([\.\-]?[a-zA-Z0-9]+)*)\.([A-Za-z]{2,})$", RegexOptions.IgnoreCase);
        }

        /// <summary>
        /// //验证是否为小数
        /// </summary>
        /// <param name="strIn"></param>
        /// <returns></returns>
        public static bool IsValidDecimal(string strIn)
        {
            return Regex.IsMatch(strIn, @"[0].d{1,2}|[1]");
        }

        /// <summary>
        /// //验证是否为小数 zhitian.zhang  新增方法
        /// </summary>
        /// <param name="strIn"></param>
        /// <returns></returns>
        public static bool IsValidDecimalV2(string strIn)
        {
            return Regex.IsMatch(strIn, @"^0\.\d+$");
        }

        /// <summary>
        /// 验证是否为固定电话号码 by sunrui 2015-06-04
        /// <para>格式形如：区号（以0开头，3或4位）-（可选）电话（7或8位）</para>
        /// </summary>
        /// <param name="strIn"></param>
        /// <returns></returns>
        public static bool IsValidTel(string strIn)
        {
            return Regex.IsMatch(strIn, @"^0(\d{2}|\d{3})[- ]?(\d{7}|\d{8})$");
        }


        /// <summary>
        /// 验证是否为手机号码
        /// </summary>
        /// <param name="strIn"></param>
        /// <param name="nationCode">验证手机加上手机国家代码 如果空则认定为国内86手机 zhitian.zhang 修改</param>
        /// <returns></returns>
        public static bool IsValidMobile(string strIn, string nationCode="86")
        {
            if (string.IsNullOrEmpty(nationCode))
            {
                nationCode = "86";
            }
            if (nationCode=="86")
            {
                if (string.IsNullOrEmpty(strIn)) return false;
                return Regex.IsMatch(strIn, @"^[1|2][3-9]\d{9}$") ? true : Regex.IsMatch(strIn, @"^234+\d{8}$", RegexOptions.IgnoreCase);
            }
            else
            {
                if(strIn.Length<6)
                {
                    return false;
                }
                else
                {
                    return true;
                }
                
            }

        }

        /// <summary>
        /// //验证年月日
        /// </summary>
        /// <param name="strIn"></param>
        /// <returns></returns>
        public static bool IsValidDate(string strIn)
        {
            return Regex.IsMatch(strIn, @"[1-2]{1}[0-9]{3}((-|\/){1}(([0]?[1-9]{1})|(1[0-2]{1}))((-|\/){1}((([0]?[1-9]{1})|([1-2]{1}[0-9]{1})|(3[0-1]{1})))( (([0-1]{1}[0-9]{1})|2[0-3]{1}):([0-5]{1}[0-9]{1}):([0-5]{1}[0-9]{1})(\.[0-9]{3})?)?)?)?$");
        }

        /// <summary>
        /// //验证后缀名
        /// </summary>
        /// <param name="strIn"></param>
        /// <returns></returns>
        public static bool IsValidPostfix(string strIn)
        {
            return Regex.IsMatch(strIn, @".(?i:gif|jpg)$");
        }

        /// <summary>
        /// //验证字符是否在4至12之间
        /// </summary>
        /// <param name="strIn"></param>
        /// <returns></returns>
        public static bool IsValidByte(string strIn)
        {
            return Regex.IsMatch(strIn, @"^[a-z]{4,12}$");
        }

        /// <summary>
        /// 是否全为字母
        /// </summary>
        /// <param name="strIn"></param>
        /// <returns></returns>
        public static bool IsValidLetter(string strIn)
        {
            return Regex.IsMatch(strIn, @"^[A-Za-z]*$");
        }

        /// <summary>
        /// 是否全为汉字
        /// </summary>
        /// <param name="strIn"></param>
        /// <returns></returns>
        public static bool IsValidChineseCharacter(string strIn)
        {
            return Regex.IsMatch(strIn, @"^[\u4e00-\u9fa5]*$");
        }

        /// <summary>
        /// //验证字符是否在指定的长度之间
        /// </summary>
        /// <param name="strIn"></param>
        /// <param name="minLen"></param>
        /// <param name="maxLen"></param>
        /// <returns></returns>
        public static bool IsValidByte(string strIn, int minLen, int maxLen)
        {
            if (string.IsNullOrEmpty(strIn) && minLen == 0)
                return true;
            else
            {
                int _strLen = Encoding.GetEncoding("GB18030").GetBytes(strIn).Length;
                if (_strLen >= minLen && _strLen <= maxLen)
                    return true;
                else
                    return false;
            }
        }

        /// <summary>
        /// //验证IP
        /// </summary>
        /// <param name="strIn"></param>
        /// <returns></returns>
        public static bool IsValidIp(string strIn)
        {
            return Regex.IsMatch(strIn, @"^(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5])$");
        }

        /// <summary>
        /// 验证身份证 建议使用VerifyIdCard 更加精准
        /// </summary>
        /// <param name="idCardNo"></param>
        /// <returns></returns>
        [Obsolete]
        public static bool CheckIDCardNo(string idCardNo)
        {
            if (!string.IsNullOrEmpty(idCardNo))
            {
                string pattern = @"(^[1-9][0-9]{5}((19[0-9]{2})|(200[0-9])|2011)(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])[0-9]{3}[0-9xX]$)";
                Match match = Regex.Match(idCardNo, pattern);
                if (match.Groups.Count > 1)
                {
                    return true;
                    //return "18位身份证号码有效!";
                }
                pattern = @"(^[1-9][0-9]{5}([0-9]{2})(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])[0-9]{3}$)";
                match = Regex.Match(idCardNo, pattern);
                if (match.Groups.Count > 1)
                {

                    return true;
                    //return "15位身份证号码有效!";
                }
            }
            return false;//"身份证号码格式不正确!";
        }
        /// <summary>
        /// 验证合法的证件号
        /// </summary>
        /// <param name="idCard"></param>
        /// <returns></returns>
        public static bool VerifyIdCard(string idCard)
        {
            if (string.IsNullOrEmpty(idCard)) return false;
            idCard = idCard.ToUpper();//带X的身份证先转成大写X
            #region 省份代码的注释说明
            //string[] aCity = new string[] { null, null, null, null, null, null, null, null, null, null, null, "北京", "天津", "河北", "山西", "内蒙古", null, null, null, null, null, "辽宁", "吉林", "黑龙江", null, null, null, null, null, null, null, "上海", "江苏", "浙江", "安微", "福建", "江西", "山东", null, null, null, "河南", "湖北", "湖南", "广东", "广西", "海南", null, null, null, "重庆", "四川", "贵州", "云南", "西藏", null, null, null, null, null, null, "陕西", "甘肃", "青海", "宁夏", "新疆", null, null, null, null, null, "台湾", null, null, null, null, null, null, null, null, null, "香港", "澳门", null, null, null, null, null, null, null, null, "国外" };
            //11: "北京", 12: "天津", 13: "河北", 14: "山西", 15: "内蒙", 
            //21: "辽宁", 22: "吉林", 23: "黑龙", 
            //31: "上海", 32: "江苏", 33: "浙江", 34: "安徽", 35: "福建", 36: "江西", 37: "山东", 
            //41: "河南", 42: "湖北", 43: "湖南", 44: "广东", 45: "广西", 46: "海南", 
            //50: "重庆", 51: "四川", 52: "贵州", 53: "云南", 54: "西藏", 
            //61: "陕西", 62: "甘肃", 63: "青海", 64: "宁夏", 65: "新疆", 
            //71: "台湾", 81: "香港", 82: "澳门", 91: "国外" }
            #endregion
            string provinceCodes = "11,12,13,14,15,21,22,23,31,32,33,34,35,36,37,41,42,43,44,45,46,50,51,52,53,54,61,62,63,64,65,71,81,82,91";
            System.Text.RegularExpressions.Regex rg = new System.Text.RegularExpressions.Regex(@"^\d{17}(\d|X)$");
            System.Text.RegularExpressions.Match mc = rg.Match(idCard);
            if (!mc.Success) return false;//基本规则不满足
            idCard = idCard.ToLower();
            idCard = idCard.Replace("x", "a");
            if (provinceCodes.IndexOf(idCard.Substring(0, 2)) < 0) return false;//前两位省份编码不满足
            try
            {
                DateTime time = DateTime.Now;
                if (!DateTime.TryParse(idCard.Substring(6, 4) + "-" + idCard.Substring(10, 2) + "-" + idCard.Substring(12, 2), out time)) return false;//出生日期格式错误，不满足
                if (time > DateTime.Now) return false;//日期为未来日期，不满足；
                if (DateTime.Now.Year - time.Year > 120) return false;//过去时间太久了，不满足
                double iSum = 0;
                for (int i = 17; i >= 0; i--)
                    iSum += (System.Math.Pow(2, i) % 11) * int.Parse(idCard[17 - i].ToString(), System.Globalization.NumberStyles.HexNumber);
                if (iSum % 11 != 1) return false;//不符合证件号标准
                return true;
            }
            catch
            {
                return false;//格式出现异常
            }

        }

        /// <summary>
        /// 验证是否中文名
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static bool IsValidateChineseName(string name)
        {
            return Regex.IsMatch(name, @"^[\u4E00-\u9FA5]{2,5}(·[\u4E00-\u9FA5]{1,5}|[\u4E00-\u9FA5]{0,5})$");
        }

        #region 只能包含数字、字母和下划线，并且不能以下划线开头和结尾
        /// <summary>
        /// 只能包含数字、字母和下划线，并且不能以下划线开头和结尾
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool IsLetterNumber_x(string source)
        {
            if (string.IsNullOrEmpty(source))
            {
                return false;
            }

            return Regex.IsMatch(source, @"^[A-Za-z0-9_]+$");
        }
        #endregion

        #region 判断是否是Touch设备
        /// <summary>
        /// 判断是否是Touch设备
        /// </summary>
        /// <param name="u"></param>
        /// <returns></returns>
        public static bool IsPhoneAttribute(string u)
        {
            Regex b = new Regex(@"android.+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            Regex v = new Regex(@"1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-", RegexOptions.IgnoreCase | RegexOptions.Multiline);

            if (!(b.IsMatch(u) || v.IsMatch(u.Substring(0, 4))))
            {
                return false;
            }

            return true;
        }
        #endregion

        #region 验证字符串长度 中文要求2-4 英文2-20
        /// <summary>
        /// 验证字符串长度 中文要求2-4 英文2-20
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool JudgeStringLength(string source)
        {
            if (string.IsNullOrEmpty(source))
            {
                return false;
            }

            source = source.Trim();

            if (source.Length < 2 || source.Length > 20)
            {
                return false;
            }

            //[1]："^[\u4e00-\u9fa5]+$"
            //说明：“^”表示字符串开头，“$”表示字符串结束，“[\u4e00-\u9fa5]+”表示一个或多个中文字符。
            //[2]："[\u4e00-\u9fa5]"
            //说明：本例中只要求判断字符串中是否出现中文，所以不需要字符串头和尾，只要在整个字符串中有中文就可以被匹配到。
            //[3]："^[\u4e00-\u9fa5]"
            //说明：在正则表达式的最前面加一个“^”，再紧跟一个中文字符，即可匹配以中文字符开头的字符串。
            //[4]："[\u4e00-\u9fa5]$"
            //说明：在正则表达式的最后面加一个“$”，在此之前加一个中文字符，即可匹配以中文字符结尾的字符串。

            bool result = Regex.IsMatch(source, @"[\u4e00-\u9fa5]", RegexOptions.Compiled);

            if (result)
            {
                if (source.Length >= 2 && source.Length <= 4)
                {
                    return true;
                }
            }
            else
            {
                if (source.Length >= 2 && source.Length <= 20)
                {
                    return true;
                }
            }

            return false;
        }
        #endregion

        #region 是否包含特殊符号
        /// <summary>
        /// 是否包含特殊符号
        /// </summary>
        /// <param name="strIn"></param>
        /// <returns></returns>
        public static bool IsContainsSymbols(string strIn)
        {
            return Regex.IsMatch(strIn, @"[`|\-|=|\[|\]|\\|;|'|,|.|\/|~|!|@|#|$|%|^|&|*|\(|\)|_|+|\{|\}|:|\<|\>|?|·|\-|=|\【|\】|、|；|‘|’|，|。|\/|~|！|@|#|￥|%|……|&|*|\（|\）|——|+|\｛|\｝|：|“|”|\《|\》|？]");
        }
        #endregion


        /// <summary>
        /// 验证微信ID是否正确
        /// </summary>
        /// <param name="weChatId"></param>
        /// <returns></returns>
        public static bool VerifyWeChatId(string weChatId)
        {
            return Regex.IsMatch(weChatId, @"^[a-zA-Z\d_]{5,}$");
        }

        /// <summary>
        /// 验证微信号是否正确
        /// 微信号正则，6至20位，以字母开头，字母，数字，减号，下划线
        /// </summary>
        /// <param name="weChatNo"></param>
        /// <returns></returns>
        public static bool VerifyWeChatNo(string weChatNo)
        {
            return Regex.IsMatch(weChatNo, @"^[-_a-zA-Z0-9]{6,20}$");
        }

        /// <summary>
        /// 商品详情图片替换为延迟加载
        /// </summary>
        /// <param name="GoodsDesc"></param>
        /// <returns></returns>
        public static string DescToLazyload(string GoodsDesc)
        {
            if (string.IsNullOrEmpty(GoodsDesc))
                return "";
            string result = Regex.Replace(GoodsDesc, "src=\"([^\"]+)\"", "src=\"https://res.qiju.com/content/o2o_LiPing/images/white.gif\" original=\"$1\"");
            return result;
        }
    }
}
